package com.tyao.note.service;

import java.io.File;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.tyao.note.mapper.BAccessoryMapper;
import com.tyao.note.mapper.BFolderMapper;
import com.tyao.note.mapper.TSUserMapper;
import com.tyao.note.model.BFolder;
import com.tyao.note.model.TSUser;
import com.tyao.note.service.exception.FolderNameAlreadyExistException;
import com.tyao.utils.FileOperate;

/**
 * 文件管理业务层
 * 
 * @author Ty-user1
 *
 */
@Service
public class FolderService {

	@Resource
	private BFolderMapper bFolderMapper;

	@Resource
	private BAccessoryMapper bAccessoryMapper;
	
	@Resource
	private AccessoryService accessoryService;

	@Resource
	private TSUserMapper tSUserMapper;

	// 获取文件保存根路径
	@Value("#{config.localFolderUri}")
	private String localFolderUri;
	// 根目录
	@Value("#{config.rootFolderName}")
	private String rootFolderName;

	/**
	 * 文件夹剪切、复制功能
	 * 
	 * @param id
	 * @param folderParentId
	 * @throws FolderNameAlreadyExistException
	 */
	public void cutOrCopy(Long id, Long folderParentId, Boolean isCut) throws FolderNameAlreadyExistException {
		// 获取文件夹信息
		BFolder bFolder = getFolderById(id);
		// 源路径
		String oldPath = getRootPath() + getFolderPathById(id);
		// 目标路径
		String newPath = getRootPath() + getFolderPathById(folderParentId) + File.separator + bFolder.getFolderName();
		// 查询目标文件夹下面是否有重名文件夹
		List<BFolder> bFolders = bFolderMapper.selectFoldersByParentId(folderParentId);
		if (!bFolders.isEmpty()) {
			for (BFolder bFolder2 : bFolders) {
				if (bFolder.getFolderName().equals(bFolder2.getFolderName())) {
					throw new FolderNameAlreadyExistException("文件名已存在");
				}
			}
		}
		boolean result = false;
		// 判断是不是剪切操作
		if (isCut) {
			result = FileOperate.moveFolder(oldPath, newPath);
			if (result) {
				bFolder.setFolderParentId(folderParentId);
				bFolderMapper.updateByPrimaryKey(bFolder);
			}
		} else {
			// 复制文件夹
			result = FileOperate.copyFolder(oldPath, newPath);
			if (result) {
				folderParentId = insertDataToSQL(bFolder.getFolderName(), bFolder.getFolderDefaut(), folderParentId, bFolder.getUserId());
				Long parentId = insertDataToSQL(id, folderParentId);
				accessoryService.saveAcc(id, parentId);
			}

		}
	}

	/**
	 * 文件夹重命名
	 * 
	 * @param id
	 * @param folderName
	 * @throws FolderNameAlreadyExistException
	 */
	public void updateFolderInfo(Long id, String folderName) throws FolderNameAlreadyExistException {
		// 获取文件夹信息
		BFolder bFolder = getFolderById(id);
		//文件夹 111  》》》 改为222
		// 获取更名前路径 如: D:/天遥航空文件管理/新建文件夹/111
		String oldAbsolutePath = getRootPath() + getFolderPathById(id);
		// 更改后的路径  如: D:/天遥航空文件管理/新建文件夹/222
		String newAbsolutePath = getRootPath() + getFolderPathById(bFolder.getFolderParentId()) + File.separator
				+ folderName;
		// 获取子文件夹信息
		List<BFolder> bFolders = bFolderMapper.selectFoldersByParentId(bFolder.getFolderParentId());
		for (BFolder folder : bFolders) {
			if (folderName.equals(folder.getFolderName())) {// 与数据库中文件名对比
				if (folder.getFolderName().equals(bFolder.getFolderName())) {
					return;
				} else {
					throw new FolderNameAlreadyExistException("文件名已存在");
				}
			} else {
				// 重命名文件夹
				boolean renameResult = new File(oldAbsolutePath).renameTo(new File(newAbsolutePath));
				if (renameResult) {
					bFolder.setFolderName(folderName);
					// 更新数据库信息
					bFolderMapper.updateByPrimaryKey(bFolder);
				}

			}
		}
	}

	/**
	 * 获取文件夹信息
	 * 
	 * @param id
	 * @return
	 */
	public BFolder getFolderById(Long id) {
		return bFolderMapper.selectByPrimaryKey(id);
	}
	/**
	 * 获取默认文件夹
	 * @return
	 */
	public BFolder getDefaultFolder() {
		return bFolderMapper.selectDefaultFolder();
	}
	/**
	 * 删除文件夹
	 * 
	 * @param id
	 * @return
	 */
	public void removeFolder(Long id, Boolean batch) {
		String path = getRootPath() + getFolderPathById(id);
		deleteDir(path);
		if (batch) {// 批量删除
			bFolderMapper.deleteBatchByParentId(id);
			for (BFolder bFolder : bFolderMapper.selectFoldersByParentId(id)) {
				bFolderMapper.deleteBatchByParentId(bFolder.getId());
			}
		} else {// 删除一个
			bFolderMapper.deleteByPrimaryKey(id);
		}
	}

	/**
	 * 获取所有的文件夹
	 * 
	 * @param userId
	 * @return
	 */
	public List<BFolder> getAllFolderByUserId(Integer userId) {
		return bFolderMapper.selectFoldersByUserId(userId);
	}

	/**
	 * 新建文件夹
	 * 
	 * @param folderName文件名
	 * @param folderDefaut默认文件夹
	 * @param folderParentId父级id
	 * @param userId
	 * @return 插入数据库后返回的主键ID
	 * @throws FolderNameAlreadyExistException文件名重复异常
	 */
	public Long insertFolder(String folderName, Long folderParentId, Integer userId)
			throws FolderNameAlreadyExistException {
		Long id = null;
		// 查询用户名下的文件夹名称是否已经存在
		List<BFolder> bFolders = bFolderMapper.selectFoldersByParentId(folderParentId);
		// 查询父级信息
		BFolder parentFolder = getFolderById(folderParentId);
		Long parentFolderId = parentFolder.getId();
		boolean mkdirResult = false;
		if (bFolders.isEmpty()) {
			// 创建文件夹
			mkdirResult = makeDir(getRootPath() + getFolderPathById(parentFolderId), folderName);
			if (mkdirResult) {// 本地文件夹创建成功，保存数据到数据库中
				id = insertDataToSQL(folderName, false, folderParentId, userId);
			}
		} else {
			for (BFolder bFolder : bFolders) {
				if (bFolder.getFolderName().equals(folderName)) {
					throw new FolderNameAlreadyExistException("文件名已存在!");
				} else {
					// 创建文件夹
					mkdirResult = makeDir(getRootPath() + getFolderPathById(parentFolder.getId()), folderName);
					if (mkdirResult) {// 本地文件夹创建成功，保存数据到数据库中
						id = insertDataToSQL(folderName, false, folderParentId, userId);
					}
				}
			}
		}
		return id;
	}

	/**
	 * 创建根目录
	 * 
	 * @param folderName
	 * @param folderDefaut
	 * @param userId
	 */
	public void insertFolder(String folderName, Boolean folderDefaut, Integer userId) {
		TSUser user = tSUserMapper.selectByPrimaryKey(userId);
		Long folderParentId = null;
		// 创建根目录
		boolean mkdirResult = makeDir(localFolderUri, rootFolderName);
		if (mkdirResult) {
			folderParentId = insertDataToSQL(rootFolderName, true, 0L, null);
		}else {
			folderParentId = bFolderMapper.selectFolderByFolderNameAndUserId(rootFolderName, null).getId();
		}
		// 创建用户文件夹
		mkdirResult = makeDir(getRootPath(), user.getUsername());
		if (mkdirResult) {
			insertDataToSQL(user.getUsername(), false, folderParentId, user.getId());
		}
	}

	/**
	 * 根路径
	 * 
	 * @return
	 */
	public String getRootPath() {
		return localFolderUri + File.separator + rootFolderName;
	}

	/**
	 * 文件路径
	 * 
	 * @param id
	 *            文件id
	 * @return 拼接的路径名称
	 */
	public String getFolderPathById(Long id) {
		List<BFolder> bFolders = bFolderMapper.selectFoldersByChildrenId(id);
		StringBuffer folderNamePath = new StringBuffer();
		for (BFolder bFolder : bFolders) {
			if (!bFolder.getFolderDefaut()) {
				folderNamePath.append(File.separator).append(bFolder.getFolderName());
			}
		}
		return folderNamePath.toString().trim();
	}

	/**
	 * 递归删除文件夹
	 * 
	 * @param path
	 *            路径
	 */
	private void deleteDir(String path) {
		File file = new File(path);
		File[] files = file.listFiles();
		if (files == null) {
			return;
		}
		for (File dir : files) {
			if (dir.isFile()) {
				dir.delete();
			}
			if (dir.isDirectory()) {
				deleteDir(dir.getAbsolutePath());
			}
		}
		file.delete();
	}

	/**
	 * 仅支持类内部调用 创建文件夹的方法
	 * 
	 * @param rootname根路径
	 * @param filename文件名
	 * @return 创建结果
	 */
	private boolean makeDir(String rootname, String foldername) {
		// 查看本地是否存在文件夹
		File localRoot = new File(new File(rootname), foldername);
		boolean localRootExist = localRoot.exists();
		// 如果不存在就创建
		boolean dirExist = false;
		if (!localRootExist) {
			dirExist = localRoot.mkdir();
		}
		return dirExist;
	}

	/**
	 * 仅支持类内部调用 插入数据库操作
	 * 
	 * @param folderName
	 * @param folderDefaut
	 * @param folderParentId
	 * @param userId
	 */
	private Long insertDataToSQL(String folderName, Boolean folderDefaut, Long folderParentId, Integer userId) {
		BFolder record = new BFolder();
		record.setFolderName(folderName);
		record.setFolderDefaut(folderDefaut);
		record.setFolderParentId(folderParentId);
		record.setUserId(userId);
		// 保存文件夹到数据库
		bFolderMapper.insertFolder(record);
		return record.getId();
	}

	/**
	 * 递归查询父级ID，并取出信息插入新一条
	 * 
	 * @param id
	 * @param folderParentId
	 */
	private Long insertDataToSQL(Long id, Long folderParentId) {
		Long parentId = folderParentId;
		while (true) {
			// 找到所有文件夹
			List<BFolder> bList = bFolderMapper.selectFoldersByParentId(id);
			if (bList.isEmpty()) {
				break;
			}else {
				for (BFolder bFolder : bList) {
					// 排除根路径和用户名命名的文件夹
					if (bFolder.getFolderDefaut() == false) {
						// 比较文件名是否和用户名一致，期望不一致时插入数据库
						String username = tSUserMapper.selectByPrimaryKey(bFolder.getUserId()).getUsername();
						if (!bFolder.getFolderName().equals(username)) {
							// 插入数据库
							parentId = insertDataToSQL(bFolder.getFolderName(), bFolder.getFolderDefaut(), parentId,
									bFolder.getUserId());
							id = bFolder.getId();
							insertDataToSQL(id, parentId);
						}
					}
				}
			}
		}
		return parentId;
	}

}
